package org.programmers.anonymous.fightrobots.manager;

import java.util.List;

import org.programmers.anonymous.fightrobots.controller.IFightController;
import org.programmers.anonymous.fightrobots.controller.IRobotController;
import org.programmers.anonymous.fightrobots.model.ActionMessage;
import org.programmers.anonymous.fightrobots.model.ErrorMessage;
import org.programmers.anonymous.fightrobots.model.IMessage;
import org.programmers.anonymous.fightrobots.model.IRobot;
import org.programmers.anonymous.fightrobots.model.IRobot.Status;
import org.programmers.anonymous.fightrobots.model.StatusMessage;
import org.programmers.anonymous.fightrobots.utils.RESTClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

/**
 * 
 * start + stop implementations
 * @author usuario
 *
 */
public class FightManager implements Runnable
{
	// crear enum de estados RUN/STOP
	// inicializar como STOP
	public enum RunStatus {START, STOP}; 
	
	boolean isOver = true;
	
	private static final Logger logger = LoggerFactory.getLogger(FightManager.class);

	protected RunStatus runStatus = RunStatus.STOP;
	
	public RunStatus getRunStatus() {
		return runStatus;
	}

	public void setRunStatus(RunStatus runStatus) {
		this.runStatus = runStatus;
	}

	@Autowired 
	protected ApplicationContext applicationContext = null;
	
	@Autowired 	
	protected IFightController fightControllerSingleton = null;
	
	@Autowired
	protected RESTClient theRESTClient = null;
	
	@Autowired
	protected IRobotController robotController = null;
	
	@Override
	public void run()
	{
		IMessage responseActionMsg = null;
		IMessage responseStatusMsg = null;
		
		// modificar estado como START
		runStatus = RunStatus.START;
		
		do{
			//Start the Fight generating the Action messages
			List<ActionMessage> listAcMsg = fightControllerSingleton.getAction();
			logger.info("Numero de robots en lista: " +listAcMsg.size());
			for(ActionMessage actionMsg: listAcMsg)
			{
				responseActionMsg = theRESTClient.executeRequest(actionMsg);
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				if(responseActionMsg instanceof ErrorMessage){
					logger.info("[" + responseActionMsg.getMySender().getRobotId() + "] >>> [" +responseActionMsg.getMyReceiver().getRobotId() +"] : I'm " +((ErrorMessage)responseActionMsg).getErrorType());
					continue;
				}
				logger.info("RESPONSE MESSAGE FROM PASSIVE: " +responseActionMsg);
				fightControllerSingleton.receiveMessage(responseActionMsg);
			}
			
			List<IRobot> listOfActiveRobot = robotController.getAllRobots();
			for(IRobot robot: listOfActiveRobot){
				logger.info("VIDA DEL ROBOT: " +robot.getLife());
			}	
			
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			logger.info(" ......................... ");
			logger.info(" ......................... Thread sleep finished ");
			logger.info(" ......................... ");
			
			//Continue the Fight generating the Status messages
			List<StatusMessage> listStMsg = fightControllerSingleton.getStatus();
			
			logger.info(" .... .... .... listStMsg.size : "  + listStMsg.size());
			
			isOver = true;
					
			for(StatusMessage statusMsg: listStMsg)
			{
				responseStatusMsg = theRESTClient.executeRequest(statusMsg);
				
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				if(responseStatusMsg == null){
					//logger.info("[" + responseStatusMsg.getMySender().getRobotId() + "] >>> [" +responseStatusMsg.getMyReceiver().getRobotId() +"] : NULL status message");
					continue;
				}
				logger.info("RESPONSE MESSAGE FROM PASSIVE-2: " +responseStatusMsg);
				
				IMessage nullStatusMsg = fightControllerSingleton.receiveMessage(responseStatusMsg);
				
				if( statusMsg.getStatus() == Status.DEAD || 
				  ((StatusMessage) responseStatusMsg).getStatus() == Status.DEAD)
				{
					isOver = isOver && true;
				}
				else
				{
					isOver = isOver && false;
				}
				
				logger.debug(" .... .... .... isOver : "  + isOver);
			}
					
		}while(!isOver);
		//Una vez acabado vuelvo a poner el RunStatus a STOP
		runStatus = RunStatus.STOP;
		logger.info(" ... ... ... Fight Manager loop finished ");
	}
}
